#include <config.h>
#include <backend_lib.h>
#include <boinc_db.h>
#include <sched_util.h>

int numX;
int numY;
int numRows;
int numResults;
int problemId;

void make_work () {
    DB_APP app;
    DB_WORKUNIT wu;
    int retval;
    int ninfiles = 2;
    char path[256];
    char wu_template[LARGE_BLOB_SIZE];
    char* command_line = NULL;
    char** infiles = new char*[2];
    char custom_file_name[256];
    char common_file_name[256];
    SCHED_CONFIG config;

    retval = config.parse_file();
    if (retval) {
	fprintf(stderr, "can't parse config file\n");
	exit(1);
    }

    retval = boinc_db.open(config.db_name, config.db_host, config.db_user, config.db_passwd);
    if (retval) {
	fprintf(stderr, "error opening database\n");
	exit(1);
    }

    retval = app.lookup("where name='hello'");
    if (retval) {
	fprintf(stderr, "app not found\n");
   	exit(1);
    }

    retval = read_filename("templates/Uncwddas_wu_template.xml", wu_template, sizeof(wu_template));
    if (retval) {
	fprintf(stderr, "cannot open WU template\n");
	exit(1);
    }

    wu.clear();

    // we must set this
    wu.appid = app.id;

    // set some defaults
    wu.min_quorum = 2;
    wu.target_nresults = 2;
    wu.max_error_results = 5;
    wu.max_total_results = 5;
    wu.max_success_results = 5;
    wu.rsc_fpops_est = 1e10;
    wu.rsc_fpops_bound = 1e11;
    wu.rsc_memory_bound = 1e8;
    wu.rsc_disk_bound = 1e8;
    wu.delay_bound = 7*86400;

    /*** create the "custom" part of the problem 
         and persist it to an xml file ***/

    // TODO create the custom part in a xml formatted file
    // FILE* f = fopen(path, "w");
    // fwrite(f, "random stuff");
    // fwrite(f, "random stuff");
    
    // determine where it should go, add to infiles, cp it there 
    sprintf(custom_file_name, "%i.xml", problemId);
    infiles[0] = custom_file_name;

    dir_hier_path(infiles[0], config.download_dir,
                            config.uldl_dir_fanout, path, true);
    
    printf("\nCustom path: %s\n", path);

    // TODO copy temp file above to custom_file_name

    /*** copy the "common" part of the problem provided by the
         researcher as a .csv file ***/

    // determine where it should go, add to infiles, cp it there
    sprintf(common_file_name, "%i.csv", problemId);
    infiles[1] = common_file_name;

    dir_hier_path(infiles[1], config.download_dir,
                            config.uldl_dir_fanout, path, true);
    printf("\nCommon path: %s\n", path);
    
    // TODO copy from {project home}/problem to common_file_name 

    // TODO create results_template.xml and add to project's dir
    create_work(
        wu,
        wu_template,
        "templates/results_template.xml",
        "templates/results_template.xml",
        const_cast<const char **>(infiles),
        ninfiles,
        config,
	command_line
    );

    boinc_db.close();
}

int main(int argc, const char** argv)
{
    int i;

    // receive num x columns
    // receive num y comumns
    // receive num rows
    // receive num results
    // receive problem id

    for (i=1; i<argc; i++) {
        if (!strcmp(argv[i], "-numX")) {
            numX = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "-numY")) {
            numY = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "-numRows")) {
            numRows = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "-numResults")) {
            numResults = atoi(argv[++i]);
        } else if (!strcmp(argv[i], "-problemId")) {
            problemId = atoi(argv[++i]);
        } else {
            fprintf(stderr, "unknown argument: %s\n", argv[i]);
        }
    }
    
    //
    // verify we have the appropriate command line arguments
    //
    #define CHKARG(x,m) do { if (!(x)) { fprintf(stderr, "workgen: bad command line: "m"\n"); exit(1); } } while (0)
    #define CHKARG_STR(v,m) CHKARG(strlen(v),m)

    CHKARG(numX , "need -numX");
    CHKARG(numY, "need -numY");
    CHKARG(numRows, "need -numRows");
    CHKARG(numResults, "need -numResults");
    CHKARG(problemId, "need -problemId");

    #undef CHKARG
    #undef CHKARG_STR

    make_work();

    return 0;
}

